package com.open.capacity.notice.statemachine.action.job;

import java.util.List;

import org.springframework.stereotype.Service;

import com.open.capacity.common.utils.BatchUtil;
import com.open.capacity.common.utils.EntityUtils;
import com.open.capacity.notice.context.SendMessageJobContext;
import com.open.capacity.notice.dmo.MessageRececiverDetail;
import com.open.capacity.notice.dmo.MessageTemplate;
import com.open.capacity.notice.dmo.SendMessageJob;
import com.open.capacity.notice.dmo.SendMessageTask;
import com.open.capacity.notice.enums.SendJobStatusChangeEnum;
import com.open.capacity.notice.enums.SendMessageTaskStatus;
import com.open.capacity.notice.event.SendMessagePublisher;
import com.open.capacity.notice.service.SendMessageJobService;
import com.open.capacity.notice.service.SendMessageTaskService;
import com.open.capacity.notice.statemachine.action.JobStateAction;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;

/**
 * 创建任务Action
 */
@Service
@SuppressWarnings("all")
@RequiredArgsConstructor
public class JobSplitAction extends JobStateAction<SendMessageJobContext> {

	private final SendMessagePublisher sendMessagePublisher;

	private final SendMessageTaskService sendMessageTaskService;

	private final SendMessageJobService sendMessageJobService;

	@Override
	public SendJobStatusChangeEnum event() {
		return SendJobStatusChangeEnum.JOB_SPLIT;
	}

	// 通过状态机context传递，fire事件触发的时候，传递进去context（拆单请求）
	@Override
	protected SendMessageJobContext onStateChangeInternal(SendJobStatusChangeEnum event,
			SendMessageJobContext context) {
		MessageTemplate template = context.getMessageTemplate();
		SendMessageJob job = context.getSendMessageJob();
		// 获取接收人
		List<MessageRececiverDetail> list = context.getMessageRececiverGroupVO().getRecevivers();
		List<SendMessageTask> sendMessageTasks = getSendMessageTasks(context, template, list);
		BatchUtil.batchHandle(sendMessageTasks.size(), 200, (offset, size) -> {
			int toIndex = Math.min(offset + size, sendMessageTasks.size());
			List<SendMessageTask> splitTasks = sendMessageTasks.subList(offset, toIndex);
			sendMessageTaskService.saveBatch(splitTasks, 100);
		});
		context.setSendMessageTasks(sendMessageTasks);
		return context;
	}

	@Override
	@SneakyThrows
	protected void postStateChange(SendJobStatusChangeEnum event, SendMessageJobContext context) {
		context.getSendMessageJob().setStatus(event.getToStatus());
		sendMessageJobService.updateById(context.getSendMessageJob());
		// 异步队列中分批处理，disruptor c/s 模型 吞吐量不够时，改用kafka/rocketmq方式
		sendMessagePublisher.publish(context.getSendMessageTasks(), context);
		
	}

	/**
	 * 分解sendtask明细
	 * @param context
	 * @param template
	 * @param message
	 * @param list
	 * @return
	 */
	private List<SendMessageTask> getSendMessageTasks(SendMessageJobContext context, MessageTemplate template,
		List<MessageRececiverDetail> list) {
		List<SendMessageTask> sendMessageTasks = EntityUtils.toList(list, item -> {
			SendMessageTask sendMessageTask = new SendMessageTask();
			SendMessageJob sendMessageJob = context.getSendMessageJob();
			sendMessageTask.setSendMessage(sendMessageJob.getSendMessage());
			sendMessageTask.setTimer(sendMessageJob.getTimer());
			sendMessageTask.setCron(sendMessageJob.getCron());
			sendMessageTask.setMsgType(template.getMsgType());
			sendMessageTask.setJobId(sendMessageJob.getId());
			sendMessageTask.setRececiverName(item.getRececiverName());
			sendMessageTask.setRececiver(item.getRececiver());
			sendMessageTask.setShield(sendMessageJob.getShield());
			sendMessageTask.setShieldTime(sendMessageJob.getShieldTime());
			sendMessageTask.setSendType(template.getSendChannel());
			sendMessageTask.setStatus(SendMessageTaskStatus.CREATED);
			sendMessageTask.setExtendInfo(sendMessageJob.getExtendInfo());
			return sendMessageTask;

		});
		return sendMessageTasks;
	}
	
	 
}
